package user

import (
	"encoding/json"
	"log"
	"net/http"
	"strings"
)

// Handler 用户HTTP处理程序
type Handler struct {
	service Service
}

// NewHandler 创建新的用户处理程序
func NewHandler(service Service) *Handler {
	return &Handler{service: service}
}

// Register 处理用户注册请求
func (h *Handler) Register(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		respondWithError(w, http.StatusMethodNotAllowed, "方法不允许", 1005)
		return
	}

	var req RegisterRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		respondWithError(w, http.StatusBadRequest, "无效的请求数据", 1006)
		return
	}

	// 验证请求数据
	if err := validateRegisterRequest(req); err != nil {
		respondWithError(w, http.StatusBadRequest, err.Error(), 1007)
		return
	}

	// 注册用户
	user, err := h.service.RegisterUser(req)
	if err != nil {
		log.Printf("注册用户失败: %v", err)
		if strings.Contains(err.Error(), "用户名已存在") {
			respondWithError(w, http.StatusConflict, "用户名已存在", 1001)
			return
		}
		respondWithError(w, http.StatusInternalServerError, "注册用户失败", 1008)
		return
	}

	// 响应成功
	respondWithJSON(w, http.StatusCreated, Response{
		Status:  "success",
		Message: "注册成功",
		Data:    user,
	})
}

// Login 处理用户登录请求
func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		respondWithError(w, http.StatusMethodNotAllowed, "方法不允许", 1005)
		return
	}

	var req LoginRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		respondWithError(w, http.StatusBadRequest, "无效的请求数据", 1006)
		return
	}

	// 验证请求数据
	if req.Username == "" || req.Password == "" {
		respondWithError(w, http.StatusBadRequest, "用户名和密码不能为空", 1007)
		return
	}

	// 用户登录
	session, err := h.service.LoginUser(req)
	if err != nil {
		log.Printf("用户登录失败: %v", err)
		if strings.Contains(err.Error(), "用户不存在") || strings.Contains(err.Error(), "密码错误") {
			respondWithError(w, http.StatusUnauthorized, "用户名或密码错误", 1002)
			return
		}
		respondWithError(w, http.StatusInternalServerError, "登录失败", 1009)
		return
	}

	// 响应成功
	respondWithJSON(w, http.StatusOK, Response{
		Status:  "success",
		Message: "登录成功",
		Data:    session,
	})
}

// Status 处理获取用户状态请求
func (h *Handler) Status(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		respondWithError(w, http.StatusMethodNotAllowed, "方法不允许", 1005)
		return
	}

	// 从请求头中获取会话ID
	sessionID := extractSessionID(r)
	if sessionID == "" {
		respondWithError(w, http.StatusUnauthorized, "未提供有效的会话ID", 1003)
		return
	}

	// 获取用户状态
	status, err := h.service.GetUserStatus(sessionID)
	if err != nil {
		log.Printf("获取用户状态失败: %v", err)
		respondWithError(w, http.StatusUnauthorized, "未登录或会话已过期", 1003)
		return
	}

	// 响应成功
	respondWithJSON(w, http.StatusOK, Response{
		Status: "success",
		Data:   status,
	})
}

// Logout 处理用户登出请求
func (h *Handler) Logout(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		respondWithError(w, http.StatusMethodNotAllowed, "方法不允许", 1005)
		return
	}

	// 从请求头中获取会话ID
	sessionID := extractSessionID(r)
	if sessionID == "" {
		respondWithError(w, http.StatusUnauthorized, "未提供有效的会话ID", 1003)
		return
	}

	// 用户登出
	err := h.service.LogoutUser(sessionID)
	if err != nil {
		log.Printf("用户登出失败: %v", err)
		respondWithError(w, http.StatusInternalServerError, "登出失败", 1010)
		return
	}

	// 响应成功
	respondWithJSON(w, http.StatusOK, Response{
		Status:  "success",
		Message: "已成功登出",
	})
}

// 辅助函数

// respondWithError 返回错误响应
func respondWithError(w http.ResponseWriter, code int, message string, errorCode int) {
	respondWithJSON(w, code, Response{
		Status:    "error",
		Message:   message,
		ErrorCode: errorCode,
	})
}

// respondWithJSON 返回JSON响应
func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
	response, err := json.Marshal(payload)
	if err != nil {
		log.Printf("JSON编码错误: %v", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(code)
	w.Write(response)
}

// extractSessionID 从请求头中提取会话ID
func extractSessionID(r *http.Request) string {
	auth := r.Header.Get("Authorization")
	if auth == "" {
		return ""
	}

	parts := strings.SplitN(auth, " ", 2)
	if len(parts) != 2 || parts[0] != "Bearer" {
		return ""
	}

	return parts[1]
}

// validateRegisterRequest 验证注册请求
func validateRegisterRequest(req RegisterRequest) error {
	if req.Username == "" {
		return ErrInvalidUsername
	}
	if len(req.Username) < 3 || len(req.Username) > 20 {
		return ErrInvalidUsername
	}
	if req.Password == "" {
		return ErrInvalidPassword
	}
	if len(req.Password) < 6 || len(req.Password) > 30 {
		return ErrInvalidPassword
	}
	if req.Email == "" {
		return ErrInvalidEmail
	}
	// 简单的Email格式验证
	if !strings.Contains(req.Email, "@") {
		return ErrInvalidEmail
	}
	return nil
}
